const { time } = require("console");

class CBaseBuff{
    constructor() {
        this.type = null;
        this.startTime = 0;
        this.endTime = 0;
        this.time = 0;//持续时间
        
    }

    init(...args) { }

    isTimeOut() {
        return this.startTime + this.time >= this.endTime;
    }

    load(...args) {
        let obj = this.target;
        let name = g_Buff.type2name[this.type];
        if (!obj || obj.getChildByName(name)) return;
        this.node = g_Buff.getBuffNode(name);
        obj.addChild(this.node);
        this.init(...args);
    }
    effect(dt) { }
}

class CPoisionBuff extends CBaseBuff{
    constructor() { 
        super();
        this.type = g_Buff.BUFF_TYPE.poision;
        this.cd = 0.2;
        this.cdtime = 0;
    }

    init(...args) {
        this.startTime = 0;
        this.endTime = args[0];
        this.time = 0;
        this.damage = args[1];
    }

    effect(dt) {
        this.cdtime += dt;
        if (this.cdtime >= this.cd) {
            this.cdtime -= this.cd;
            g_Monster.receiveDamage(this.target, this.damage, DAMAGE_TYPE.POISION);
        }
    }
}

class CFireBuff extends CBaseBuff{
    constructor() { 
        super();
        this.type = g_Buff.BUFF_TYPE.fire;
        this.cd = 0.2;
        this.cdtime = 0;
    }
    init(...args) {
        this.startTime = 0;
        this.endTime = args[0];
        this.time = 0;
        this.damage = args[1];
    }

    effect(dt) {
        this.cdtime += dt;
        if (this.cdtime >= this.cd) {
            this.cdtime -= this.cd;
            g_Monster.receiveDamage(this.target, this.damage, DAMAGE_TYPE.FIRE);
        }
    }
}

class CBuffManager{
    constructor() {
        this.buffid = 1;
        this.allBuff = {};

        this.BUFF_TYPE = {//buff类型定义
            poision: 1,
            fire: 2,
        }
        this.buffPrefab = {}//存所有buff预制体
        this.type2name = {
            [this.BUFF_TYPE.poision]: "poisionBuff",//做对象的键时用[对象], []取值, buff预制体
            [this.BUFF_TYPE.fire]: "fireBuff",
        }
        this.loadBuff();
    }

    loadBuff() {
        for (let type in this.type2name) { 
            //异步加载资源：  
            //cc.loader.loadRes(资源路径，资源类型，回调函数)
            cc.loader.loadRes("buff/" + this.type2name[type], cc.Prefab, (err, item) => { //加载资源
                if (err) {
                    console.log("加载资源失败");
                    return;
                }
                this.buffPrefab[this.type2name[type]] = item;
            })
        }
        
    }

    getBuffNode(name) {
        return cc.instantiate(this.buffPrefab[name]);
    }

    createBuff(type) { 
        switch (type) { 
            case this.BUFF_TYPE.poision:
                return new CPoisionBuff();
            case this.BUFF_TYPE.fire:
                return new CFireBuff();
            default:
                return new CBaseBuff();
        }
    }

    addBuff(obj, type, ...args) {//...args 剩余参数
        let name = this.type2name[type];
        if (obj.getChildByName(name)) return;
        let buff = this.createBuff(type);
        buff.id = this.buffid++;
        this.allBuff[buff.id] = buff;
        buff.target = obj;
        buff.load(...args);
    }

    removeBuff(buff) {
        delete this.allBuff[buff.id];
        buff.node.destroy();
    }

    clear() {
        this.allBuff = {};
    }

    update(dt) {
        let lstRemove = [];
        for (let id in this.allBuff) {
            let buff = this.allBuff[id];
            buff.time += dt;
            if (buff.isTimeOut()) {
                lstRemove.push(id);
            } else {
                buff.effect(dt);
            }
        }
        for (let id of lstRemove) { 
            this.removeBuff(this.allBuff[id]);
        }
    }
}

window.g_Buff = new CBuffManager();